home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / utils / initsnb.zoo / init / ac / ac.c next >
C/C++ Source or Header  |  1992-01-29  |  4KB  |  236 lines

  1. /*
  2.  * ac - login accounting
  3.  * (C) 1992 D P Gymer
  4.  * $Log: ac.c,v $
  5.  * Revision 0.2  1992/01/28  18:34:32  dpg
  6.  * Altered printout format to match the SunOS version.
  7.  *
  8.  * Revision 0.1  1992/01/25  19:09:16  dpg
  9.  * Initial revision.
  10.  *
  11.  */
  12.  
  13. #include <fcntl.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <time.h>
  18. #include <unistd.h>
  19. #include <utmp.h>
  20.  
  21. #define WTMP    "/var/adm/wtmp"
  22.  
  23. char rcsid[] = "$Id: ac.c,v 0.2 1992/01/28 18:34:32 dpg Exp $";
  24.  
  25. #define NSIZE    8
  26. #define NCPY(n1, n2)    (strncpy(n1, n2, NSIZE))
  27. #define NCMP(n1, n2)    (strncmp(n1, n2, NSIZE))
  28. #define BLINE(rec)    (!strncmp("~", rec->ut_line, 8))
  29.  
  30. /* ASSUMPTION - every day has the same number of seconds. */
  31. #define SECSPERDAY    (24L * 60L * 60L)
  32. #define SECSPERHOUR    (60L * 60L)
  33.  
  34. #define USER    0x0001
  35. #define DAILY    0x0002
  36. int flags = 0;
  37.  
  38. struct time {
  39.     time_t total;
  40.     time_t last;
  41.     char name[NSIZE];    /* Magic number alert! */
  42.     struct time *next;
  43. };
  44.  
  45. static void
  46. outtime(date, name, time)
  47.     char *date;
  48.     char *name;
  49.     time_t time;
  50. {
  51.     if (!date)
  52.         date = "";
  53.     if (!name)
  54.         name = "total";
  55.     printf("%-8.8s %-8.8s %4ld.%02ld\n", date, name, time / SECSPERHOUR,
  56.         ((time % SECSPERHOUR) * 100L) / SECSPERHOUR);
  57. }
  58.  
  59. static void
  60. check_boot(list, rec)
  61.     struct time *list;
  62.     struct utmp *rec;
  63. {
  64.     if (!BLINE(rec))
  65.         return;
  66.     while (list) {
  67.         if (list->last
  68. #ifdef SHUTDOWN_LOGIN
  69.             && (NCMP(list->name, "shutdown") ||
  70.             !NCMP(rec->ut_name, "reboot"))
  71. #endif
  72.             )
  73.         {
  74.             list->total += rec->ut_time - list->last;
  75.             list->last = 0;
  76.         }
  77.         list = list->next;
  78.     }
  79. }
  80.  
  81. static struct time *
  82. update_time(rec, name, list)
  83.     struct utmp *rec;
  84.     char *name;
  85.     struct time *list;
  86. {
  87.     struct time **timep = &list;
  88.  
  89.     while (*timep && NCMP((*timep)->name, name))
  90.         timep = &(*timep)->next;
  91.     if (!*timep)
  92.         if (!(*timep = (struct time *) malloc(sizeof (struct time)))) {
  93.             perror("ac");
  94.             exit(1);
  95.         } else {
  96.             NCPY((*timep)->name, name);
  97.             (*timep)->total = (*timep)->last = 0;
  98.             (*timep)->next = 0;
  99.         }
  100.     if (*rec->ut_name)
  101.         (*timep)->last = rec->ut_time;
  102.     else if ((*timep)->last) {
  103.         (*timep)->total += rec->ut_time - (*timep)->last;
  104.         (*timep)->last = 0;
  105.     }
  106.     return list;
  107. }
  108.  
  109. static void
  110. print_time(list, current, date)
  111.     struct time *list;
  112.     time_t current;
  113.     char *date;
  114. {
  115.     time_t total = 0;
  116.  
  117.     while (list) {
  118.         if (list->last) {    /* Still logged on. */
  119.             list->total += current - list->last;
  120.             list->last = current;
  121.         }
  122.         if (list->total && flags & USER)
  123.             outtime((char *) 0, list->name, list->total);
  124.         total += list->total;
  125.         list->total = 0;
  126.         list = list->next;
  127.     }
  128.     outtime(date, (char *) 0, total);
  129. }
  130.  
  131. static int
  132. same_day(t1, t2)
  133.     time_t t1;
  134.     time_t t2;
  135. {
  136.     return t1 / SECSPERDAY != t2 / SECSPERDAY;
  137. }
  138.  
  139. static void
  140. new_day(list, newtime)
  141.     struct time *list;
  142.     time_t newtime;
  143. {
  144.     char date[16];
  145.     time_t ltime;
  146.  
  147.     if (newtime) {
  148.         newtime -= newtime % SECSPERDAY;
  149.         ltime = newtime - 1;
  150.     } else
  151.         ltime = time(&newtime);
  152.     strftime(date, 16, "%b %d", localtime(<ime));
  153.     print_time(list, newtime, date);
  154. }
  155.  
  156. static int
  157. ignore_user(users, name, rec)
  158.     char **users;
  159.     char *name;
  160.     struct utmp *rec;
  161. {
  162.     if (BLINE(rec))
  163.         return 1;
  164.     if (!*users)
  165. #ifdef SHUTDOWN_LOGIN
  166.         return !NCMP(name, "shutdown");
  167. #else
  168.         return 0;
  169. #endif
  170.     while (*users)
  171.         if (!NCMP(*users++, name))
  172.             return 0;
  173.     return 1;
  174. }
  175.  
  176. static int
  177. perform_ac(users, file)
  178.     char **users;
  179.     char *file;
  180. {
  181.     int fd;
  182.     struct utmp rec;
  183.     char who[NSIZE];
  184.     struct time *list = 0;
  185.     time_t ltime = 0;
  186.  
  187.     if ((fd = open(file, O_RDONLY)) < 0) {
  188.         perror(file);
  189.         return 1;
  190.     }
  191.     while (read(fd, &rec, sizeof(struct utmp)) == sizeof(struct utmp)) {
  192.         if (*rec.ut_name)
  193.             NCPY(who, rec.ut_name);
  194.         if (ltime && flags & DAILY && same_day(ltime, rec.ut_time))
  195.             new_day(list, rec.ut_time);
  196.         check_boot(list, &rec);
  197.         ltime = rec.ut_time;
  198.         if (!ignore_user(users, who, &rec))
  199.             list = update_time(&rec, who, list);
  200.     }
  201.     close(fd);
  202.     if (flags & DAILY)
  203.         new_day(list, (time_t) 0);
  204.     else
  205.         print_time(list, time((time_t *) 0), (char *) 0);
  206.     return 0;
  207. }
  208.  
  209. int
  210. main(argc, argv)
  211.     int argc;
  212.     char **argv;
  213. {
  214.     int c;
  215.     char *wtmp = WTMP;
  216.     extern int optind;
  217.     extern char *optarg;
  218.  
  219.     while ((c = getopt(argc, argv, "dpw:")) != EOF)
  220.         switch (c) {
  221.         case 'd':
  222.             flags |= DAILY;
  223.             break;
  224.         case 'p':
  225.             flags |= USER;
  226.             break;
  227.         case 'w':
  228.             wtmp = optarg;
  229.             break;
  230.         default:
  231.             return 1;
  232.         }
  233.  
  234.     return perform_ac(argv + optind, wtmp);
  235. }
  236.